Skip to content

perf: overlap MTP final-draft-to-target graph updates.#1962

Draft
pjgao wants to merge 6 commits into
xLLM-AI:mainfrom
pjgao:perf/npu-mtp-tp2-gapless
Draft

perf: overlap MTP final-draft-to-target graph updates.#1962
pjgao wants to merge 6 commits into
xLLM-AI:mainfrom
pjgao:perf/npu-mtp-tp2-gapless

Conversation

@pjgao

@pjgao pjgao commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

目标与范围

本 PR 只优化 NPU MTP speculative decoding 中 final draft 完成到 target verification graph 启动 的边界。

这样拆分后,本 PR 的性能归因和评审范围都只对应一个 pipeline 边界。

问题

优化前,最后一个 draft token 已经生成后,target graph 仍要串行等待 host 完成:

  1. verify token 拼装及 dtype 转换;
  2. positions、KV lengths、slots、block table 和 linear-state metadata 更新;
  3. expanded paged-attention tiling 更新;
  4. ACL graph task 更新与 replay 提交。

这些工作位于 final draft → target 的关键路径上,形成 host dispatch 空泡。

实现

1. 提前准备可静态确定的 target graph task

在 final draft 执行期间准备与最终 token 无关的 target graph task,并为动态输入保留稳定地址。final draft 完成后只保留真实的数据依赖,不再重新构建整套 target 输入。

2. 在 target graph 开头融合动态输入更新

新增三个 TileLang kernel family:

  • spec_verify_token_update:写入 base token 与各 draft token;
  • spec_verify_metadata_update:更新 positions、KV lengths、slots、block table、linear state 等 persistent metadata;
  • spec_verify_attention_tiling_update:更新 expanded paged-attention 的动态 tiling 字段。

三类更新被 target graph 捕获,避免 replay 前额外的 graph-external D2D、同步 memcpy 或 ATB Setup。

3. 用模型能力契约替代模型名硬编码

新增 SpeculativeVerifyCapabilities

  • requires_causal_chunked_prefill
  • supports_in_graph_input_update

MTP runtime 只查询能力,不再判断 qwen3_5mimo 等模型字符串。能力在 target model 加载时缓存,decode 热路径不重复执行虚调用或字符串匹配。

  • Qwen3.5 hybrid:需要 causal chunked-prefill,并支持当前 expanded-attention/linear-state graph 输入布局;
  • MiMo:需要 causal chunked-prefill,但不进入当前 graph input update 快路径;
  • 其他模型:默认关闭,继续使用原有保守路径;后续模型适配只需在模型层声明并验证能力。

4. MTP3、MTP4、MTP5 使用同一条快路径

框架控制流不再写死 depth == 5verify width == 6。TileLang 针对当前已验证的有限硬件形状生成:

speculative depth verify width specialization
MTP3 4 w4 / w4_bt64 / w4_bs128
MTP4 5 w5 / w5_bt64 / w5_bs128
MTP5 6 w6 / w6_bt64 / w6_bs128

其他深度、multi-sequence、地址不稳定或布局不满足要求时自动回退到原路径。本 PR 不宣称支持任意 speculative depth 或 MTP8。

代码规模

相对 main@abe92b83f

  • 32 个文件;+2587/-142
  • production:+2123/-139
  • tests:+464/-3

主要分布:

模块 文件数 代码量
runtime / ACL graph 12 +1241/-129
TileLang Python kernels 3 +359
TileLang C++ wrapper / wiring 5 +378
framework capability contract 4 +112/-10
model adapters 2 +33
tests 6 +464/-3

batch_test.cpp 中另有 +3/-3 的 latest-main 测试 API 迁移,只用于保持该已有测试可编译,不影响 runtime。

提交拆分

提交按依赖顺序组织,reviewer 可以逐层检查:

顺序 commit 评审主题 规模
1 391a9855f speculative verification 模型能力契约 3 files,+54
2 2c5ba940b 三个 TileLang graph update kernel family 及 wrapper 8 files,+737
3 b73cddbb8 persistent graph 输入与融合更新 3 files,+396/-39
4 6edabdbf1 executor/ACL graph task 提前准备与 replay plumbing 8 files,+465/-7
5 fd80f16b4 MTP worker 接入、模型适配和 MTP3/4/5 快路径 4 files,+471/-93
6 26abdf093 TileLang、ACL graph 和 batch compatibility 测试 6 files,+464/-3

每个提交只承担一个评审主题。拆分前后的 Git tree 均为 d0de856c31eb106821900bca929ba2774e9fd900,因此本次历史整理没有改变任何最终源码内容。

性能证据

main 与 #1962 语义版本

固定条件:Qwen3.5-2B、target TP2、draft body TP1、MTP5、NPU 14/15;ACL graph、schedule overlap、chunked prefill 开启;固定输入集,输出 25 tokens;warmup 8 后执行 20 requests × 3 rounds,共 60/60 成功请求。

指标 main main + #1962 变化
TTFT 83.710 ms 82.592 ms -1.34%
TPOT 3.1063 ms 2.7557 ms -11.29%
decode throughput 321.922 tok/s 362.878 tok/s +12.72%
E2E output throughput 157.966 tok/s 168.090 tok/s +6.41%
25-token E2E 158.26 ms 148.73 ms -6.02%

accepted/draft 均为 1617/2610,输出内容及 token usage 一致。

这里的约 148.73 ms#1962 单独能力的可归因结果。约 145.9 ms 的历史结果来自 #1962#1966 组合版本,不作为本 PR 的单独收益声明。

通用化重构开销

在固定 Qwen3.5-2B、TP2、MTP5 workload 上做过 A-B-A 重构前后测试:TPOT -0.0278%、25-token E2E +0.0081%、吞吐 -0.0084%,均小于 0.04% 且低于 2% 回退门槛。

该测试来自通用化开发 lane,属于强支持证据;在 PR 从 Draft 切换为 Ready 前,仍会对当前精确 head 26abdf093 补做 main/MTP3/MTP4/MTP5 同合同正式 A/B,不把旧 lineage 的绝对数冒充为当前 head 数据。

当前 head 验证

  • git diff --check:通过;
  • 三个 TileLang kernel family 强制生成:通过;
  • 本次改动涉及的 runtime、model registry、ACL graph 和 TileLang wrapper production translation units:编译通过;
  • spec_verify_token_update_wrapper_test:4/4 通过;
  • spec_verify_metadata_update_wrapper_test:3/3 通过;
  • spec_verify_attention_tiling_update_wrapper_test:2/2 通过;
  • NPU TileLang 单测合计:9/9 通过。

回退边界

以下任一条件不满足时均使用原实现:

  • 模型未声明当前 graph input layout capability;
  • 非 NPU 或 ACL graph/feature gate 关闭;
  • multi-sequence;
  • speculative depth 不在 MTP3–5;
  • stable source address、graph key、block-table width 或 tensor layout 不匹配。

因此 Kimi、DeepSeek、DFlash 以及其他尚未适配的模型不会误入 Qwen3.5 的 fast path。

@pjgao
pjgao force-pushed the perf/npu-mtp-tp2-gapless branch from 65a1958 to a74b00f Compare July 19, 2026 14:40
@pjgao pjgao changed the title perf: eliminate final draft-to-target bubbles for qwen3.5 mtp on npu. perf(npu): overlap MTP final-draft-to-target graph updates Jul 19, 2026
@pjgao

pjgao commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author

PR #1962 已刷新到 a74b00f56,本次 force-with-lease 更新基于最新 main@abe92b83f

本轮主要变化:

  • PR 范围收敛为 final draft → target verification graph,不包含 perf: eliminate validate-to-draft bubbles with asynchronous device-side handoff. #1966 的 target → next draft 优化;
  • 删除 Qwen3.5/MiMo target model 字符串门控,改为模型声明 SpeculativeVerifyCapabilities
  • 将旧的 handoff kernel/API 统一重命名为 spec_verify_*_update,明确表达 graph 输入更新语义;
  • MTP3/4/5 共用一条 runtime 快路径,对应 verify width 4/5/6;
  • 其他模型、深度和布局默认走保守 fallback。

当前 head 已通过改动 production translation units 编译、TileLang kernel 生成及 NPU wrapper 单测 9/9。PR 描述已区分可归属于 #1962 的约 148.73 ms E2E 与 #1962+#1966 组合版本的约 145.9 ms,避免错误归因。

当前 PR 保持 Draft;切换 Ready 前会补充精确 head a74b00f56 的 main/MTP3/MTP4/MTP5 同合同正式 A/B。

@pjgao pjgao changed the title perf(npu): overlap MTP final-draft-to-target graph updates perf: overlap MTP final-draft-to-target graph updates. Jul 19, 2026
@pjgao
pjgao force-pushed the perf/npu-mtp-tp2-gapless branch from a74b00f to 26abdf0 Compare July 19, 2026 15:05
pjgao added 4 commits July 19, 2026 23:05
- default unsupported models to the conservative runtime path
- allow model implementations to declare verification requirements
- fuse token and persistent metadata writes for graph replay
- update dynamic paged-attention tiling for verify widths 4, 5, and 6
- retain stable graph addresses for dynamic verification sources
- apply fused token, metadata, and tiling updates during replay
- expose static graph-task preparation through the executor stack
- preserve source identity and reuse captured replay tasks safely
@pjgao

pjgao commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author

按评审主题重新拆分提交并更新远端,当前 head 为 26abdf093

  1. 391a9855f:模型能力契约,3 files / +54
  2. 2c5ba940b:TileLang graph update kernels,8 files / +737
  3. b73cddbb8:persistent graph inputs,3 files / +396/-39
  4. 6edabdbf1:ACL graph task 提前准备,8 files / +465/-7
  5. fd80f16b4:MTP runtime 与 MTP3/4/5 接入,4 files / +471/-93
  6. 26abdf093:测试,6 files / +464/-3

拆分前 a74b00f56 与拆分后 26abdf093 的 Git tree 都是 d0de856c31eb106821900bca929ba2774e9fd900,最终源码内容字节级一致;本次仅整理提交历史,没有改变实现和既有验证结论。

旧的已发布历史仍保存在本地 backup/pr1962-pre-review-split-a74b00f56,如有问题可以精确恢复。

pjgao added 2 commits July 19, 2026 23:06
- prepare static target work while the final draft step executes
- use model capabilities and fused graph updates for MTP3, MTP4, and MTP5
- retain conservative fallback behavior for unsupported layouts
- validate TileLang specializations for MTP3, MTP4, and MTP5
- cover graph task reuse and current batch block-manager APIs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant